﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Framework.Infrastructure;
using Microsoft.Practices.Unity;
using System.Reflection;
using NServiceBus;
using Framework.Event;
using Framework.Bus;

namespace Framework.Config
{
    public static class FrameworkConfigurationExtension
    {
        static IBus _Bus;
        public static Configuration NServieBusBuild(this Configuration configuration)
        {
            if (_Bus == null)
            {
                var config = Configure.With()
                        .DefineEndpointName(Configuration.GetAppConfig("EndPointName"))
                        .DefaultBuilder();

                
                config = config.DefiningEventsAs(t => typeof(IDomainEvent).IsAssignableFrom(t));


                config = config.DefiningCommandsAs(t => typeof(Framework.Command.ICommand).IsAssignableFrom(t));
               
                _Bus = config.JsonSerializer()
                      .MsmqSubscriptionStorage()
                      .MsmqTransport()
                      .IsTransactional(true)
                      .UnicastBus()
                      .CreateBus()
                      .Start(() => Configure.Instance
                                .ForInstallationOn<NServiceBus.Installation.Environments.Windows>()
                                .Install());

                IoCFactory.Instance.CurrentContainer.RegisterInstance(typeof(IBus)
                                                                        , "NSB"
                                                                        , _Bus
                                                                        , new ContainerControlledLifetimeManager());

                config.Configurer.ConfigureComponent<IMessageDispatcher>(() =>
                {
                    return IoCFactory.Resolve<IMessageDispatcher>(Constants.Configuration.CommandDispatcher);
                }, DependencyLifecycle.InstancePerUnitOfWork);
            }
          
            return configuration;
        }

    }
}
